<?php
namespace PsiFramework\Classes\Util\Manager;

import("Classes.Util.HTTP.Session");

use \PsiFramework\Classes\Util\HTTP\Session;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The ObjectManager class
 *
 * @package Manager
 */
class ObjectManager
{

    protected static $_singleton = null;

    protected /*string[]*/ $_primitives  ;
    protected /*string[]*/ $_primitiveObjects ;
    protected /*string[]*/ $_objects ;

    protected function __construct()
    {
        $this->_primitives = array(
            "string",
            "text",
            "int",
            "integer",
            "long",
            "float",
            "double",
            "boolean",
            "bool"
        );

        $this->_primitiveObjects = array(
            "Date" => array(
                "class"=>"Classes.Util.Object.Date",
                "dao"  =>"Classes.Util.DAO.DateDAO"
            ),
            "File" => array(
                "class"=>"Classes.Util.Object.File",
                "dao"  =>"Classes.Util.DAO.FileDAO"
            ),
            "Image" => array(
                "class"=>"Classes.Util.Object.Image",
                "dao"  =>"Classes.Util.DAO.ImageDAO"
            ),
            "ImageCollection" => array(
        		"class"=>"Classes.Util.Object.ImageCollection",
        		"dao"  =>"Classes.Util.DAO.ImageCollectionDAO"
            ),
            "Json" => array(
                "class"=>"Classes.Util.Object.Json",
                "dao"  =>"Classes.Util.DAO.JsonDAO"
            ),
            "ReferenceObject" => array(
                "class"=>"Classes.Util.Object.ReferenceObject",
                "dao"  =>"Classes.Util.DAO.RegerenceObjectDAO"
            ),
              "TreeviewNodeCollection" => array(
                "class"=>"Classes.Util.Object.Treeview.TreeviewNodeCollection",
                "dao"  =>"Classes.Util.DAO.Treeview.TreeviewNodeCollectionDAO"
            ),
            "TreeviewNode" => array(
                "class"=>"Classes.Util.Object.Treeview.TreeviewNode",
                "dao"  =>"Classes.Util.DAO.Treeview.TreeviewNodeDAO"
            ),

            "ObjectParameters" => array(
                "class"=>"Classes.Util.Parameters.ObjectParameters",
                "dao"  =>"Classes.Util.Parameters.DAO.ObjectParametersDAO"
            ),
            "JsonParameters" => array(
                "class"=>"Classes.Util.Parameters.JsonParameters",
                "dao"  =>"Classes.Util.Parameters.DAO.JsonParametersDAO"
            )
        ) ;

        $this->_objects = array();
    }

    public function __destruct()
    {
        Session::getInstance()->set('object_manager', $this);
    }

    public function isPrimitive(/*string*/ $type)
    {
        return in_array(strtolower($type), $this->_primitives);
    }

    public function isPrimitiveObject(/*string*/ $type)
    {
        return array_key_exists($type, $this->_primitiveObjects);
    }

    public function isObject(/*string*/ $type)
    {
        return in_array($type, $this->_objects);
    }

    public function importPrimitiveObject(/*string*/ $type)
    {
        $absoluteName = '' ;
        if ($this->isPrimitiveObject($type)) {
            $absoluteName = $this->_primitiveObjects[$type]['class'] ;
            import($absoluteName);
            $absoluteName = '\\PsiFramework\\' . str_replace('.', '\\', $absoluteName);
            
        }
        return $absoluteName ;
    }

    public function getPrimitiveObjectInstance(/*string*/ $type)
    {
        if ($this->isPrimitiveObject($type)) {
        	$path = $this->_primitiveObjects[$type]['class'] ;
            import($path);
            $className = getClassName($path);
            return new $className();
        } else {
            return null ;
        }
    }

    public function importPrimitiveObjectDao(/*string*/ $type)
    {
        if ($this->isPrimitiveObject($type)) {
            $daoPath = $this->_primitiveObjects[$type]['dao'] ;
            if (!isNullOrEmptyString($daoPath)) {
                import($daoPath);
            }
        }
    }

    public function getPrimitiveObjectDaoInstance(/*string*/ $type)
    {
        if ($this->isPrimitiveObject($type)) {
            $dao = $type . 'DAO' ;
            $daoPath = $this->_primitiveObjects[$type]['dao'] ;
            if (!isNullOrEmptyString($daoPath)) {
                import($daoPath);
                $className = getClassName($daoPath);
                return call_user_func(array($className, 'getInstance'));
            } else {
                return null ;
            }
        } else {
            return null ;
        }
    }

    public function addPrimitiveObject(
        /*string*/ $type,
        /*string*/ $classPath,
        /*string*/ $daoPath=null
    )
    {
        $this->_primitiveObjects[$type]
            = array('class'=>$classPath, 'dao'=>$daoPath);
    }

    public function addObject(/*string*/ $type)
    {
        $this->_objects[] = $type ;
    }

    /**
     * Function to be called instead of the constructor.
     *
     * @return     ObjectManager instance
     */
    public static function getInstance()
    {

        if (self::$_singleton==null) {
            self::$_singleton= Session::getInstance()->get('object_manager');
            if (self::$_singleton==null) {
                self::$_singleton = new ObjectManager();
            }
        }

        return self::$_singleton;
    }
}
